package com.yunpeng.aidevice.biz.service.impl;

import com.yunpeng.aidevice.biz.service.IPermissionBizService;
import com.yunpeng.aidevice.common.constant.QueryConstants;
import com.yunpeng.common.dto.Result;
import com.yunpeng.aidevice.common.enums.ResultCodeEnum;
import com.yunpeng.common.enums.QueryOperatorEnum;
import com.yunpeng.common.exception.BizException;
import com.yunpeng.common.paging.PagingQueryDTO;
import com.yunpeng.common.paging.query.QueryParam;
import com.yunpeng.aidevice.common.vo.PermissionDetailVO;
import com.yunpeng.aidevice.common.vo.RolePermissionVO;
import com.yunpeng.aidevice.common.vo.user.UserPermissionVO;
import com.yunpeng.aidevice.common.vo.org.OrgPermissionVO;
import com.yunpeng.aidevice.dao.constant.DictionariesConstant;
import com.yunpeng.aidevice.dao.model.entity.PermissionDO;
import com.yunpeng.aidevice.dao.model.entity.UserDO;
import com.yunpeng.aidevice.dao.model.relation.OrganizationPermissionDO;
import com.yunpeng.aidevice.dao.model.relation.RolePermissionDO;
import com.yunpeng.aidevice.dao.model.relation.UserOwnPermissionDO;
import com.yunpeng.aidevice.dao.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * PermissionBizServiceImpl
 *
 * @author : Moore(hemw)
 * @date : 2020-04-15
 */
@Service
public class PermissionBizServiceImpl implements IPermissionBizService {

    @Resource
    private IPermissionService permissionService;

    @Resource
    private IUserService userService;

    @Resource
    private IRoleService roleService;

    @Resource
    private IOrganizationService organizationService;

    @Resource
    private IListQueryService listQueryService;

    @Override
    /**
     * 新增权限项
     *
     * @param name         权限项名称
     * @param operatorCode 操作人代码
     * @return
     */
    public Result<Void> addNew(String name, String operatorCode) {
        if (permissionService.addNew(name, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 删除权限项
     *
     * @param permissionCode 权限项代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> remove(String permissionCode, String operatorCode) {
        Date now = new Date();
        StringBuilder reasonBuilder = new StringBuilder();
        boolean canRemove = true;
        if (organizationService.countPermissionRelation(permissionCode, null, now) > 0) {
            reasonBuilder.append("存在组织机构配置了此权限，请解绑后删除！");
            canRemove = false;
        }
        if (roleService.countPermissionRelation(permissionCode, null) > 0) {
            reasonBuilder.append("存在角色配置了此权限，请解绑后删除！");
            canRemove = false;
        }
        if (userService.countPermissionRelation(permissionCode, null, now) > 0) {
            reasonBuilder.append("存在用户配置了此权限，请解绑后删除！");
            canRemove = false;
        }
        if (canRemove) {
            if (permissionService.remove(permissionCode, operatorCode)) {
                return Result.success();
            }
            return Result.fail(ResultCodeEnum.REMOVE_FAILED);
        }
        return Result.build(ResultCodeEnum.REMOVE_FAILED.getValue(), reasonBuilder.toString());
    }

    @Override
    /**
     * 禁用权限
     *
     * @param permissionCode 权限代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> disabled(String permissionCode, String operatorCode) {
        if (permissionService.disabled(permissionCode, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 启用权限
     *
     * @param permissionCode 权限代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> enabled(String permissionCode, String operatorCode) {
        if (permissionService.enabled(permissionCode, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 权限服务端列表分页查询
     *
     * @param name        名称（左匹配）
     * @param pageSize    （页数据数量，1-100，默认10）
     * @param currentPage （当前页码，默认1）
     * @return
     */
    public Result<PagingQueryDTO> queryList(String name, Integer pageSize, Integer currentPage) {
        PagingQueryDTO pagingQueryDTO = new PagingQueryDTO();
        List<QueryParam> queryParams = new ArrayList<>();
        LinkedHashMap<String, String> orderByMap = new LinkedHashMap<>(16);
        //设置查询条件
        if (StringUtils.isNotBlank(name)) {
            queryParams.add(QueryParam.quickSetQueryParam("name", name, QueryOperatorEnum.LEFT_LIKE));
        }
        queryParams.add(QueryParam.quickSetQueryParam("flag", 1, QueryOperatorEnum.EQUALS));
        queryParams.add(QueryParam.quickSetQueryParam("tenant_code", DictionariesConstant.INSTANCE.getDefaultTenantCode(), QueryOperatorEnum.EQUALS));
        //设置排序
        orderByMap.put("update_time", "desc");
        orderByMap.put("id", "desc");
        pagingQueryDTO.setCurrentPage(currentPage);
        pagingQueryDTO.setPageSize(pageSize);
        pagingQueryDTO.setConditionList(queryParams);
        pagingQueryDTO.setSortColumnMap(orderByMap);
        PagingQueryDTO resultData = listQueryService.query(pagingQueryDTO, QueryConstants.QUERY_PERMISSION_LIST_4_SERVICE_SIDE, null);
        return Result.success(resultData);
    }


    @Override
    /**
     * 权限详情数据
     *
     * @param permissionCode 权限代码
     * @return
     */
    public Result<PermissionDetailVO> permissionDetail(String permissionCode) {
        PermissionDO permissionDO = permissionService.getByCode(permissionCode);
        if (permissionDO == null || permissionDO.getId() == null) {
            return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
        }
        List<UserOwnPermissionDO> userOwnPermissionDOList = permissionService.queryUserPermissionListByPermission(permissionCode);
        List<RolePermissionDO> rolePermissionDOList = permissionService.queryRolePermissionListByPermission(permissionCode);
        List<OrganizationPermissionDO> organizationPermissionDOList = permissionService.queryOrgPermissionListByPermission(permissionCode);
        PermissionDetailVO permissionDetailVO = new PermissionDetailVO();
        permissionDetailVO.setName(permissionDO.getName());
        permissionDetailVO.setCode(permissionDO.getCode());
        permissionDetailVO.setDisabled(permissionDO.getDisabled());
        if (rolePermissionDOList != null && rolePermissionDOList.size() > 0) {
            permissionDetailVO.setRoles(rolePermissionDOList.stream().map(t -> new RolePermissionVO(t.getRoleCode(), t.getRoleName(), t.getPermissionCode(), t.getPermissionName())).collect(Collectors.toList()));
        }
        if (userOwnPermissionDOList != null && userOwnPermissionDOList.size() > 0) {
            permissionDetailVO.setUsers(userOwnPermissionDOList.stream().map(t -> new UserPermissionVO(t.getUserCode(), t.getUserName(), t.getPermissionCode(), t.getPermissionName(), t.getStartDate(), t.getEndDate())).collect(Collectors.toList()));
        }
        if (organizationPermissionDOList != null && organizationPermissionDOList.size() > 0) {
            permissionDetailVO.setOrganizations(organizationPermissionDOList.stream().map(t -> new OrgPermissionVO(t.getOrganizationCode(), t.getOrganizationName(), t.getPermissionCode(), t.getPermissionName(), t.getStartDate(), t.getEndDate())).collect(Collectors.toList()));
        }
        return Result.success(permissionDetailVO);
    }


    @Override
    /**
     * 绑定权限到用户
     *
     * @param userCode       用户代码
     * @param permissionCode 权限代码
     * @param startDate      起始生效时间
     * @param endDate        生效截止时间
     * @param operatorCode   操作人代码
     * @param merchantCode   商户代码
     * @return
     */
    public Result<Void> userBindPermissions(String userCode, String permissionCode, Date startDate, Date endDate, String operatorCode, String merchantCode) {
        UserDO userDO = userService.getByCode(userCode, merchantCode, DictionariesConstant.INSTANCE.getDefaultTenantCode());
        if (userDO == null || userDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "用户不存在");
        }
        PermissionDO permissionDO = permissionService.getByCode(permissionCode);
        if (permissionDO == null || permissionDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "权限不存在");
        }
        UserOwnPermissionDO userOwnPermissionDO = new UserOwnPermissionDO();
        userOwnPermissionDO.initForNew(operatorCode);
        userOwnPermissionDO.setUserCode(userDO.getCode());
        userOwnPermissionDO.setUserName(userDO.getName());
        userOwnPermissionDO.setPermissionCode(permissionDO.getCode());
        userOwnPermissionDO.setPermissionName(permissionDO.getName());
        userOwnPermissionDO.setStartDate(startDate);
        userOwnPermissionDO.setEndDate(endDate);
        if (permissionService.bindUserPermission(userOwnPermissionDO)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 用户权限解绑
     *
     * @param userCode       用户代码
     * @param permissionCode 权限代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> unbindUserPermissions(String userCode, String permissionCode, String operatorCode) {
        if (permissionService.unbindUserPermission(userCode, permissionCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 组织机构权限分页列表
     *
     * @param organizationName 组织机构名（左匹配）
     * @param permissionName   权限名（左匹配）
     * @param pageSize         （页数据数量，1-100，默认10）
     * @param currentPage      （当前页码，默认1）
     * @return
     */
    public Result<PagingQueryDTO> queryOrgPermissionList(String organizationName, String permissionName, Integer pageSize, Integer currentPage) {
        PagingQueryDTO pagingQueryDTO = new PagingQueryDTO();
        List<QueryParam> queryParams = new ArrayList<>();
        LinkedHashMap<String, String> orderByMap = new LinkedHashMap<>(16);
        //设置查询条件
        if (StringUtils.isNotBlank(organizationName)) {
            queryParams.add(QueryParam.quickSetQueryParam("organization_name", organizationName, QueryOperatorEnum.LEFT_LIKE));
        }
        if (StringUtils.isNotBlank(organizationName)) {
            queryParams.add(QueryParam.quickSetQueryParam("permission_name", permissionName, QueryOperatorEnum.LEFT_LIKE));
        }
        queryParams.add(QueryParam.quickSetQueryParam("flag", 1, QueryOperatorEnum.EQUALS));
        //设置排序
        orderByMap.put("update_time", "desc");
        orderByMap.put("id", "desc");
        pagingQueryDTO.setCurrentPage(currentPage);
        pagingQueryDTO.setPageSize(pageSize);
        pagingQueryDTO.setConditionList(queryParams);
        pagingQueryDTO.setSortColumnMap(orderByMap);
        PagingQueryDTO resultData = listQueryService.query(pagingQueryDTO, QueryConstants.QUERY_ORG_PERMISSION_LIST_4_SERVICE_SIDE, null);
        return Result.success(resultData);
    }

    @Override
    /**
     * 绑定权限到组织机构
     *
     * @param orgCode        组织机构代码
     * @param permissionCode 权限代码
     * @param startTime      起始生效时间
     * @param endTime        生效截止时间
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> bindPermissionToOrg(String orgCode, String permissionCode, Date startTime, Date endTime, String operatorCode) {
        if (permissionService.bindPermissionToOrg(permissionCode, orgCode, startTime, endTime, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 解除组织机构的权限绑定
     *
     * @param orgCode        组织机构代码
     * @param permissionCode 权限代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> unbindPermissionFromOrg(String orgCode, String permissionCode, String operatorCode) {
        if (permissionService.unbindPermissionFromOrg(permissionCode, orgCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }
}
